from django.utils import timezone
from rest_framework import status
from rest_framework.response import Response
# from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication

import logging

from tsl_backend import jwt
import tsl_backend.users.models as users
import tsl_backend.fgr_api.views.fgr_apis as fgr_apis
import tsl_backend.frontend_api.serializers.auth_serializers as auth_serializers

from tsl_backend.frontend_api.middleware import response as frontend_response


def parse_perm(user_account_obj):
    account_perm = users.RolePermission.objects.filter(
        role=user_account_obj.role, flow=user_account_obj.department.flow
    ).first()
    serializer = auth_serializers.RolePermissionSerializer(account_perm)
    return serializer.data

class AuthView(APIView):
    def post(self, request):
        logging.info(f"User login: {request.data['username']}")
        message, token = jwt.get_tokens_for_ewo_user(
            username=request.data["username"],
            password=request.data["password"],
        )
        if token is not None:
            user = users.User.objects.get(
                username=request.data["username"]
            )
            accounts = users.Account.objects.filter(
                django_user=user, enable=True
            ).order_by("department__flow").prefetch_related("django_user", "role", "department")

            account_departments = [{
                "id": account.id, # new added
                "userCode": account.user_code, # new added
                "deptCode": account.department.code,
                "role": account.role.name,
                "role_chinese_name": account.role.chinese_name,
                "deptName": account.department.name,
                "department": account.department.flow.chinese_name,
                "Source": account.department.site.name,
                "perm":parse_perm(account)
            } for account in accounts]


            # data = {
            #         "token": {
            #             "access": token["access_token"],
            #             "refresh": token["refresh_token"],
            #         },
            #         "accounts": {
            #             "cnName": user.cnName,
            #             "staffcode": user.staffcode,
            #             "domestic": [
            #                 dept for dept in account_departments if dept["Source"] == "4083"
            #             ],
            #             "export": [
            #                 dept for dept in account_departments if dept["Source"] == "1062"
            #             ],
            #             "others":[
            #                 dept for dept in account_departments if dept["Source"] != "4083" or dept["Source"] != "1062"
            #             ]
            #         },
            #     }

            data = {
                    "token": {
                        "access": token["access_token"],
                        "refresh": token["refresh_token"],
                    },
                    "accounts": {
                        "cnName": user.cnName,
                        "staffcode": user.staffcode,
                        "domestic": [],
                        "export": [],
                        "others":[]
                    },
                }
            
            for dept in account_departments:
                if dept["Source"] == "1062":
                    data["accounts"]["export"].append(dept)
                elif dept["Source"] == "4083":
                    data["accounts"]["domestic"].append(dept)
                else:
                    data["accounts"]["others"].append(dept)

            logging.info(f"No. of accounts for domestic: {len(data['accounts']['domestic'])}")
            logging.info(f"No. of accounts for export: {len(data['accounts']['export'])}")
            logging.info(f"No. of accounts for others: {len(data['accounts']['others'])}")

            return Response(
                data,
                status=status.HTTP_200_OK
            )
        else:
            return Response(
                # {"detail": "No active account found with the given credentials"},
                {"detail": message},
                status=status.HTTP_401_UNAUTHORIZED
            )

    def get(self, request):
        """
        ping and get server date time
        """
        return Response({"date_time": timezone.now().strftime("%Y-%m-%d %H:%M:%S")})

class LogoutView(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [JWTAuthentication]

    def post(self, request):
        refresh_token = request.data.get('refresh_token')

        if refresh_token:
            try:
                jwt.blacklist_token(refresh_token)
            except Exception as e:
                logging.error(f"Exception to logout: {e}")
                return Response({'error': 'Invalid token'}, status=status.HTTP_400_BAD_REQUEST)
            return Response(status=status.HTTP_205_RESET_CONTENT)
        else:
            return Response({'error': 'Token not provided'}, status=status.HTTP_400_BAD_REQUEST)

class UpdatePWView(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [JWTAuthentication]
    serializer_class = auth_serializers.UpdatePWDSerializer

    def post(self, request):
        oldPWD = request.data.get('oldPWD')
        newPWD_ = request.data.get('newPWD')
        staffcode = request.data.get('staffcode')
        if oldPWD and newPWD_:
            resetMode="password"
            newPWD=newPWD_["_rawValue"]
            success=fgr_apis.updatePwd(staffcode, oldPWD, newPWD, resetMode)
            if success:
                message="Success"
                data=None
                return frontend_response(status.HTTP_200_OK, message, data)
                # return Response({"status": True, "msg": "Success"}, status=status.HTTP_200_OK)
            else:
                message="Fail to update password"
                data=None
                return frontend_response(status.HTTP_200_OK, message, data)
                # return Response({"status": False, "msg": "Fail to update password"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            message="Incorrect old/new password"
            data=None
            return frontend_response(status.HTTP_200_OK, message, data)
            # return Response({"status": False, 'msg': 'Incorrect old/new password'}, status=status.HTTP_400_BAD_REQUEST)